Python и CGI-программирование. Введение Web программирование
Одна из главных сфер применения языка Python - web-приложения. Под web-приложением будет пониматься программа, основнойинтерфейс пользователя которой работает в стандартном WWW-браузере под управлением HTML и XML-документов. Для улучшениякачества интерфейса пользователя часто применяют JavaScript, однако это несколько снижает универсальность интерфейса. Следует заметить,что интерфейс можно построить на Java- или Flash-апплетах, однако, такие приложения сложно назвать web-приложениями, так как Java илиFlash могут использовать собственные протоколы для общения ссервером, а не стандартный для WWW протокол HTTP.
CGI (Common Gateway Interface, общий интерфейс шлюза) -- протокол для запуска внешних по отношению к web-серверу приложений (CGI-скриптов), регулирует коммуникацию между HTTP-сервером и CGI-скриптами.
При поступлении запроса на URL, который Web-сервер настроен считать CGI-скриптом, сервер вызывает скрипт, передавая ему информацию через стандартный ввод, переменные окружения и (для ISINDEX) -- через аргументы командной строки.
Примечание: кроме того, для передачи ISINDEX
могут использоваться аргументы командной строки. В Python
они доступны в списке sys.argv.
Два основных метода передачи данных из заполненной в браузере формы
Web-серверу (и CGI-скрипту) -- method="GET" и
method="POST". В зависимости от метода данные передаются
по-разному. В первом случае они кодируются и помещаются прямо
в URL, типа: http://host/cgi-bin/a.cgi?a=1&b=3.
Скрипт получает их в переменной окружения QUERY_STRING.
Во втором случае они передаются на стандартный ввод.
Следющий простейший скрипт выводит значения из словаря os.environ:
#!/usr/bin/python import os print """Content-Type: text/plain %s""" % os.environ
С помощью него можно увидеть установленные Web-сервером переменные окружения.
Основные переменные окружения следующие:
Пример:
{
'DOCUMENT_ROOT': '/var/www/html',
'SERVER_ADDR': '127.0.0.1',
'SERVER_PORT': '80',
'GATEWAY_INTERFACE': 'CGI/1.1',
'HTTP_ACCEPT_LANGUAGE': 'en-us, en;q=0.50',
'REMOTE_ADDR': '127.0.0.1',
'SERVER_NAME': 'rnd.onego.ru',
'HTTP_CONNECTION': 'close',
'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.0.1) Gecko/20021003',
'HTTP_ACCEPT_CHARSET': 'ISO-8859-1, utf-8;q=0.66, *;q=0.66',
'HTTP_ACCEPT': 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1',
'REQUEST_URI': '/cgi-bin/test.py?a=1',
'PATH': '/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin',
'QUERY_STRING': 'a=1&b=2',
'SCRIPT_FILENAME': '/var/www/cgi-bin/test.py',
'HTTP_KEEP_ALIVE': '300',
'HTTP_HOST': 'localhost',
'REQUEST_METHOD': 'GET',
'SERVER_SIGNATURE': 'Apache/1.3.23 Server at rnd.onego.ru Port 80',
'SCRIPT_NAME': '/cgi-bin/test.py',
'SERVER_ADMIN': 'root@localhost',
'SERVER_SOFTWARE': 'Apache/1.3.23 (Unix) (Red-Hat/Linux) mod_python/2.7.8 Python/1.5.2 PHP/4.1.2',
'SERVER_PROTOCOL': 'HTTP/1.0',
'REMOTE_PORT': '39251'
}
В Python имеется поддержка CGI в виде модуля cgi.
пример:
#!/usr/bin/python
import cgi, os
# анализ запроса
f = cgi.FieldStorage()
if f.has_key("a"):
a = f["a"].value
else:
a = "0"
# обработка запроса
b = str(int(a)+1)
mytext = open(os.environ["SCRIPT_FILENAME"]).read()
mytext_html = cgi.escape(mytext)
# формированиве ответа
print """Content-Type: text/html
<html><head><title>Решение примера: %(b)s = %(a)s + 1</title></head>
<body>
%(b)s
<table width="80%%"><tr><td>
<form action="me.cgi" method="GET">
<input type="text" name="a" value="0" size="6">
<input type="submit" name="b" value="Обработать">
</form></td></tr></table>
<pre>
%(mytext_html)s
</pre>
</body></html>""" % vars()
В этом примере к заданному в форме числу прибавляется 1.
Кроме того, выводится исходный код самого скрипта.
Заметьте, что для экранирования символов >, <, &
применена функция cgi.escape(). И еще.
Для формирования Web-страницы использована операция форматирования.
В качестве словаря -- словарь vars() со всеми
локальными переменными. Знаки процента пришлось удвоить
(для задания ширины таблицы).
В примере выше проверка на допустимость произведена при
вызове функции int(): если бы было задано нечисло,
скрипт бы аварийно завершился, а пользователь
увидел бы Internal Server Error
После анализа входных данных можно выделить фазу их обработки. В этой части CGI-скрипта вычисляются переменные для дальнейшего вывода. Здесь необходимо учитывать не только значения переданных переменных, но и факт их присутствия или отсутствия, так как это тоже может влиять на логику скрипта.
И наконец, фаза вывода готового объекта (текста, HTML-документа, изображения, мультимедиа-объекта и т.п.).
Следующий пример выдает черный квадрат:
#!/usr/bin/python
import sys
print """Content-Type: image/jpeg
"""
import Image
i = Image.new("RGB", (10,10))
i.im.draw_rectangle((0,0,10,10), 1)
i.save(sys.stdout, "jpeg")
Для формирования HTML-документа можно использовать и специальные средства, обсуждение которых можно найти на http://www.python.org/topics/web/HTML.html
Обычно при создании Web-приложений стараются отделить Форму (внешний вид, стиль), Содержание и Логику обработки данных. В приведенном выше примере Логика отделена от Формы и Содержания. (Последние в силу простоты примера не отделены.)
Для создания Web-приложений применяются и более сложные средства, например, Zope (Z Object Publishing Environment, среда публикации объектов). Zope имеет встроенный web-сервер, но может работать и с другими Web-серверами, например, Apache.
Для ускорения работы CGI (для Apache) используется различные схемы, например, FastCGI или PCGI (Persistent CGI).